import csv
import os.path

import matplotlib
import networkx as nx
import pandas as pd
import matplotlib.pyplot as plt
import requests
import json
from tqdm import tqdm
from pyecharts.charts import Geo
from pyecharts import options as opts
from pyecharts.globals import GeoType
import webbrowser
from datetime import datetime
from logging import Logger

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
# matplotlib.use("TkAgg")
class Utils:
    @classmethod
    def read_map(cls,file_path:str)->nx.Graph:
        graph = nx.Graph()
        node_data = pd.read_excel(file_path,"node")
        edge_data = pd.read_excel(file_path,"edge")
        for index, row in node_data.iterrows():
            id = row["id"]
            name=row["name"]
            lat = row["lat"]
            lon = row["lon"]
            graph.add_node(id,name=name,lat=lat,lon=lon)
        for index, row in edge_data.iterrows():
            id = row["id"]
            name=row["name"]
            start_id = row["start_id"]
            end_id=row["end_id"]
            len = row["len"]
            graph.add_edge(start_id,end_id,id=id,name=name,len=len)
        return graph

    @classmethod
    def read_data(cls,file_path):
        node_data = pd.read_excel(file_path, "node", header=0)
        edge_data = pd.read_excel(file_path, "edge", header=0)
        # 此处应该进行一个校验
        return node_data, edge_data

    @classmethod
    def get_position(cls, addr):
        para = {'key': '7e25cc6f441b12825c0e4db59d1ed778',  # 高德Key
                'address': addr}  # 地址参数
        url = 'https://restapi.amap.com/v3/geocode/geo?'  # 高德地图地理编码API服务地址
        result = requests.get(url, para)  # GET方式请求
        result = result.json()
        try:
            if int(result["count"])!=1:
                # 如果获取到的数量不等于1，则记录后交由人工判定
                with open(os.path.join(os.getcwd(),"data","json",f"{addr}.json"),"w") as file:
                    file.write(json.dumps(result))
            lon_lat = result['geocodes'][0]['location']  # 获取返回参数geocodes中的location，即经纬度
            # print(f"已获取{addr}的经纬度坐标：{lon_lat}")
            return lon_lat
        except Exception as e:
            return '-1.0,-1.0'


    @classmethod
    def get_position_by_excel(cls, file_path):
        df = pd.read_excel(file_path, header=0)
        try:
            for i in tqdm(range(len(df)-3,len(df))):
                # print(df.loc[i,"名称"])
                addr = df.loc[i,"name"]+"火车站"
                location = Utils.get_position(addr)
                df.loc[i, "lon"]=location.split(",")[1]
                df.loc[i, "lat"] = location.split(",")[0]
        except Exception as e:
            print(f"{addr}经纬度获取出错")
        finally:
            df.to_excel(os.path.join(os.getcwd(),"data","vertex_with_location22.xlsx"),index=False)
            

    @classmethod
    def show_map(cls):
        g = Geo().add_schema(maptype="china")
        node_data, edge_data = Utils.read_data(os.path.join(os.getcwd(),"src","data.xlsx"))
        # 标点
        for i in range(len(node_data)):
            node =  node_data.iloc[i]
            g.add_coordinate(node["name"],node["lon"],node["lat"])
        data_pair = [(node_data.iloc[i]["name"],1) for i in range(len(node_data))]
        g.add("",data_pair, type_=GeoType.EFFECT_SCATTER, symbol_size=2)
        # 标绘边
        edge_pairs = []
        for i in range(len(edge_data)):
            edge = edge_data.iloc[i]
            edge_pairs.append((edge["start_id"],edge["end_id"]))
        g.add("", edge_pairs, type_=GeoType.LINES, is_polyline=True,
              linestyle_opts=opts.LineStyleOpts(width=0.5, opacity=0.5))
        g.set_series_opts(label_opts=opts.LabelOpts(is_show=False))
        g.set_global_opts(title_opts=opts.TitleOpts(title="中国铁路站点图"))

        result = g.render(os.path.join(os.getcwd(),"data","stations.html"))

        webbrowser.open_new_tab(result)
    
    @classmethod
    def draw_line(cls, line_name):
        g = Geo().add_schema(maptype="china")
        node_data, edge_data = Utils.read_data(os.path.join(os.getcwd(),"src","data.xlsx"))
        # 标点
        # for i in range(len(node_data)):
        #     node = node_data.iloc[i]
        #     g.add_coordinate(node["name"], node["lon"], node["lat"])
        # data_pair = [(node_data.iloc[i]["name"], 1) for i in range(len(node_data))]
        # g.add("", data_pair, type_=GeoType.EFFECT_SCATTER, symbol_size=2)
        
        # 标绘边
        node_pairs = []
        edge_pairs = []
        for i in range(len(edge_data)):
            edge = edge_data.iloc[i]
            if edge["name"] == line_name:
                start_node = node_data[node_data["id"] == edge["start_id"]].iloc[0]
                g.add_coordinate(start_node["name"], start_node["lon"], start_node["lat"])
                node_pairs.append((start_node["name"], 1))
                end_node = node_data[node_data["id"] == edge["end_id"]].iloc[0]
                g.add_coordinate(end_node["name"], end_node["lon"], end_node["lat"])
                node_pairs.append((end_node["name"], 1))
                edge_pairs.append((start_node["name"], end_node["name"]))
        
        g.add("", node_pairs, type_=GeoType.EFFECT_SCATTER, symbol_size=1)
        g.add("", edge_pairs, type_=GeoType.LINES, is_polyline=True,
              linestyle_opts=opts.LineStyleOpts(width=0.2, opacity=0.7))
        g.set_series_opts(label_opts=opts.LabelOpts(is_show=True))
        g.set_global_opts(title_opts=opts.TitleOpts(title=f"{line_name}线路图"))

        result = g.render(os.path.join(os.getcwd(), "data", f"{line_name}_line.html"))

        webbrowser.open_new_tab(result)

    @classmethod
    def read_dbf(cls, file_name):
        from dbfread import DBF
        table = DBF(filename=file_name,encoding="utf-8")
        dbf_data = list(table)
        return dbf_data
        
    @classmethod
    def data_update(cls):
        node_data, _ = Utils.read_data(os.path.join(os.getcwd(),"src","data.xlsx"))
        dbf_data = Utils.read_dbf(os.path.join(os.getcwd(),"data","火车站.dbf"))
        for station in tqdm(dbf_data):
            node_data.loc[node_data["id"]+"站" == station["站名简"],"lat"]=station["WGS84_Lat"]
            node_data.loc[node_data["id"]+"站" == station["站名简"],"lon"]=station["WGS84_Lng"]
        node_data.to_excel(os.path.join(os.getcwd(),"data","node_update.xlsx"))

    @classmethod
    def degree_2_float(cls, degree_str:str):
        degree = 0
        minute = 0
        second = 0
        if len(degree_str.split('.'))>1:
            degree = degree_str.split('.')[0]
            if len(degree_str.split('.')[1])>0:
                minute = degree_str.split('.')[1][:2]
            elif len(degree_str.split('.')[1])>2:
                second = degree_str.split('.')[1][2:]
            return int(degree)+int(minute)/60.0+int(second)/3600.0
        else:
            return float(degree_str)
        
    @classmethod
    def get_lat_lon_by_baidu(cls, addr):
        # 服务地址
        host = "https://api.map.baidu.com"

        # 接口地址
        uri = "/geocoding/v3"

        # 此处填写你在控制台-应用管理-创建应用后获取的AK
        ak = "GIyz6W0xTEu5jitUxigptDR5stvZ2j7X"

        params = {
            "address": addr,
            "output": "json",
            "ak":ak,
        }

        response = requests.get(url = host + uri, params = params)
        if response:
            print(response.json())
            return response.json()
        else:
            return None

    @classmethod
    def unit_change(cls, file_name):
        nodes, _ = Utils.read_data(file_name)
        for i in range(len(nodes)):
            data = nodes.iloc[i]
            lat1 = str(data["lat1"])
            lon1 = str(data["lon1"])
            if len(lat1)>0:
                nodes.loc[i,"lat"] = Utils.degree_2_float(lat1)
                nodes.loc[i,"lon"] = Utils.degree_2_float(lon1)
        nodes.to_excel(os.path.join(os.getcwd(),"data","更改.xlsx"))


if __name__ == '__main__':
    util = Utils()

    # df = pd.read_excel(os.path.join(os.getcwd(),"src","data.xlsx"),sheet_name="edge")
    # id_series  = df["id"].unique()
    # for i in tqdm(range(len(id_series))):
    #     util.draw_line(id_series[i])

    # util.draw_line("青盐线")
    util.show_map()

    # graph = Utils.read_map(os.path.join(os.getcwd(),"src","data.xlsx"))
    # Utils.read_dbf(os.path.join(os.getcwd(),"data","火车站.dbf"))
    # Utils.data_update()

    # hello = list(Utils.read_dbf(os.path.join(os.getcwd(),"data","china-latest.osm.dbf")))
    # print(hello)

    # 通过百度地图查询所有难查的地址经纬度
    # data = pd.read_excel(os.path.join(os.getcwd(),"data","difficult_to_search.xlsx"))
    # for i in tqdm(range(len(data))):
    #     addr = data.loc[i,"name"]
    #     if addr.endswith("所"):
    #         addr = addr.replace("所","线路所")
    #     else:
    #         addr = addr+"火车站"
    #     res = Utils.get_lat_lon_by_baidu(addr)
    #     if res is not None:
    #         try:
    #             data.loc[i,"lat"]=res["result"]["location"]["lat"]
    #             data.loc[i,"lon"]=res["result"]["location"]["lng"]
    #         except Exception as e:
    #             continue
    # data.to_excel(os.path.join(os.getcwd(),"data","difficult_to_search_solved.xlsx"))

    # Utils.get_position_by_excel(os.path.join(os.getcwd(),"data","node2.xlsx"))
    
